﻿namespace System.Web.Mvc
{
    using System;
    using System.Linq.Expressions;
    using System.Web.Routing;

    /// <summary>
    /// Route collection extension methods class.
    /// </summary>
    public static class RouteCollectionExtensions
    {
        /// <summary>
        /// Adds a typed route into a RouteCollection.
        /// </summary>
        /// <typeparam name="TController">The controller type.</typeparam>
        /// <param name="routes">The route collection to fill in.</param>
        /// <param name="routeName">Name of the route.</param>
        /// <param name="url">The URL for the route.</param>
        /// <param name="action">The controller action.</param>
        [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1006:DoNotNestGenericTypesInMemberSignatures", Justification = "I expect this behavior as I want a lambda expression of that type.")]
        [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1054:UriParametersShouldNotBeStrings", MessageId = "2#", Justification = "The Url parameter is correcly named as it represents an Url but it should not be of Url type as it is a specially formatted string.")]
        public static void MapRoute<TController>(
            this RouteCollection routes,
            string routeName,
            string url,
            Expression<Func<TController, ActionResult>> action)
            where TController : IController
        {
            if (routes == null)
            {
                throw new ArgumentNullException("routes");
            }

            var typedControllerAction = new ControllerAction<TController>(action);

            routes.Add(routeName, new Route(url, typedControllerAction.DefaultValues, new MvcRouteHandler()));
        }
    }
}
